/**
 * @license AngularJS v1.2.4
 * (c) 2010-2014 Google, Inc. http://angularjs.org
 * License: MIT
 */

(function () {
    'use strict';

    /**
     * @description
     *
     * This object provides a utility for producing rich Error messages within
     * Angular. It can be called as follows:
     *
     * var exampleMinErr = minErr('example');
     * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
     *
     * The above creates an instance of minErr in the example namespace. The
     * resulting error will have a namespaced error code of example.one.  The
     * resulting error will replace {0} with the value of foo, and {1} with the
     * value of bar. The object is not restricted in the number of arguments it can
     * take.
     *
     * If fewer arguments are specified than necessary for interpolation, the extra
     * interpolation markers will be preserved in the final string.
     *
     * Since data will be parsed statically during a build step, some restrictions
     * are applied with respect to how minErr instances are created and called.
     * Instances should have names of the form namespaceMinErr for a minErr created
     * using minErr('namespace') . Error codes, namespaces and template strings
     * should all be static strings, not variables or general expressions.
     *
     * @param {string} module The namespace to use for the new minErr instance.
     * @returns {function(string, string, ...): Error} instance
     */

    function minErr(module) {
        return function () {
            var code = arguments[0],
                prefix = '[' + (module ? module + ':' : '') + code + '] ',
                template = arguments[1],
                templateArgs = arguments,
                stringify = function (obj) {
                    if (typeof obj === 'function') {
                        return obj.toString().replace(/ \{[\s\S]*$/, '');
                    } else if (typeof obj === 'undefined') {
                        return 'undefined';
                    } else if (typeof obj !== 'string') {
                        return JSON.stringify(obj);
                    }
                    return obj;
                },
                message, i;

            message = prefix + template.replace(/\{\d+\}/g, function (match) {
                    var index = +match.slice(1, -1), arg;

                    if (index + 2 < templateArgs.length) {
                        arg = templateArgs[index + 2];
                        if (typeof arg === 'function') {
                            return arg.toString().replace(/ ?\{[\s\S]*$/, '');
                        } else if (typeof arg === 'undefined') {
                            return 'undefined';
                        } else if (typeof arg !== 'string') {
                            return toJson(arg);
                        }
                        return arg;
                    }
                    return match;
                });

            message = message + '\nhttp://errors.angularjs.org/1.2.4/' +
                (module ? module + '/' : '') + code;
            for (i = 2; i < arguments.length; i++) {
                message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
                    encodeURIComponent(stringify(arguments[i]));
            }

            return new Error(message);
        };
    }

    /**
     * @ngdoc interface
     * @name angular.Module
     * @description
     *
     * Interface for configuring angular {@link angular.module modules}.
     */

    function setupModuleLoader(window) {

        var $injectorMinErr = minErr('$injector');
        var ngMinErr = minErr('ng');

        function ensure(obj, name, factory) {
            return obj[name] || (obj[name] = factory());
        }

        var angular = ensure(window, 'angular', Object);

        // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
        angular.$$minErr = angular.$$minErr || minErr;

        return ensure(angular, 'module', function () {
            /** @type {Object.<string, angular.Module>} */
            var modules = {};

            /**
             * @ngdoc function
             * @name angular.module
             * @description
             *
             * The `angular.module` is a global place for creating, registering and retrieving Angular
             * modules.
             * All modules (angular core or 3rd party) that should be available to an application must be
             * registered using this mechanism.
             *
             * When passed two or more arguments, a new module is created.  If passed only one argument, an
             * existing module (the name passed as the first argument to `module`) is retrieved.
             *
             *
             * # Module
             *
             * A module is a collection of services, directives, filters, and configuration information.
             * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
             *
             * <pre>
             * // Create a new module
             * var myModule = angular.module('myModule', []);
             *
             * // register a new service
             * myModule.value('appName', 'MyCoolApp');
             *
             * // configure existing services inside initialization blocks.
             * myModule.config(function($locationProvider) {
     *   // Configure existing providers
     *   $locationProvider.hashPrefix('!');
     * });
             * </pre>
             *
             * Then you can create an injector and load your modules like this:
             *
             * <pre>
             * var injector = angular.injector(['ng', 'MyModule'])
             * </pre>
             *
             * However it's more likely that you'll just use
             * {@link ng.directive:ngApp ngApp} or
             * {@link angular.bootstrap} to simplify this process for you.
             *
             * @param {!string} name The name of the module to create or retrieve.
             * @param {Array.<string>=} requires If specified then new module is being created. If
             *        unspecified then the the module is being retrieved for further configuration.
             * @param {Function} configFn Optional configuration function for the module. Same as
             *        {@link angular.Module#methods_config Module#config()}.
             * @returns {module} new module with the {@link angular.Module} api.
             */
            return function module(name, requires, configFn) {
                var assertNotHasOwnProperty = function (name, context) {
                    if (name === 'hasOwnProperty') {
                        throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
                    }
                };

                assertNotHasOwnProperty(name, 'module');
                if (requires && modules.hasOwnProperty(name)) {
                    modules[name] = null;
                }
                return ensure(modules, name, function () {
                    if (!requires) {
                        throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
                            "the module name or forgot to load it. If registering a module ensure that you " +
                            "specify the dependencies as the second argument.", name);
                    }

                    /** @type {!Array.<Array.<*>>} */
                    var invokeQueue = [];

                    /** @type {!Array.<Function>} */
                    var runBlocks = [];

                    var config = invokeLater('$injector', 'invoke');

                    /** @type {angular.Module} */
                    var moduleInstance = {
                        // Private state
                        _invokeQueue: invokeQueue,
                        _runBlocks: runBlocks,

                        /**
                         * @ngdoc property
                         * @name angular.Module#requires
                         * @propertyOf angular.Module
                         * @returns {Array.<string>} List of module names which must be loaded before this module.
                         * @description
                         * Holds the list of modules which the injector will load before the current module is
                         * loaded.
                         */
                        requires: requires,

                        /**
                         * @ngdoc property
                         * @name angular.Module#name
                         * @propertyOf angular.Module
                         * @returns {string} Name of the module.
                         * @description
                         */
                        name: name,


                        /**
                         * @ngdoc method
                         * @name angular.Module#provider
                         * @methodOf angular.Module
                         * @param {string} name service name
                         * @param {Function} providerType Construction function for creating new instance of the
                         *                                service.
                         * @description
                         * See {@link AUTO.$provide#provider $provide.provider()}.
                         */
                        provider: invokeLater('$provide', 'provider'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#factory
                         * @methodOf angular.Module
                         * @param {string} name service name
                         * @param {Function} providerFunction Function for creating new instance of the service.
                         * @description
                         * See {@link AUTO.$provide#factory $provide.factory()}.
                         */
                        factory: invokeLater('$provide', 'factory'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#service
                         * @methodOf angular.Module
                         * @param {string} name service name
                         * @param {Function} constructor A constructor function that will be instantiated.
                         * @description
                         * See {@link AUTO.$provide#service $provide.service()}.
                         */
                        service: invokeLater('$provide', 'service'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#value
                         * @methodOf angular.Module
                         * @param {string} name service name
                         * @param {*} object Service instance object.
                         * @description
                         * See {@link AUTO.$provide#value $provide.value()}.
                         */
                        value: invokeLater('$provide', 'value'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#constant
                         * @methodOf angular.Module
                         * @param {string} name constant name
                         * @param {*} object Constant value.
                         * @description
                         * Because the constant are fixed, they get applied before other provide methods.
                         * See {@link AUTO.$provide#constant $provide.constant()}.
                         */
                        constant: invokeLater('$provide', 'constant', 'unshift'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#animation
                         * @methodOf angular.Module
                         * @param {string} name animation name
                         * @param {Function} animationFactory Factory function for creating new instance of an
                         *                                    animation.
                         * @description
                         *
                         * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
                         *
                         *
                         * Defines an animation hook that can be later used with
                         * {@link ngAnimate.$animate $animate} service and directives that use this service.
                         *
                         * <pre>
                         * module.animation('.animation-name', function($inject1, $inject2) {
           *   return {
           *     eventName : function(element, done) {
           *       //code to run the animation
           *       //once complete, then run done()
           *       return function cancellationFunction(element) {
           *         //code to cancel the animation
           *       }
           *     }
           *   }
           * })
                         * </pre>
                         *
                         * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
                         * {@link ngAnimate ngAnimate module} for more information.
                         */
                        animation: invokeLater('$animateProvider', 'register'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#filter
                         * @methodOf angular.Module
                         * @param {string} name Filter name.
                         * @param {Function} filterFactory Factory function for creating new instance of filter.
                         * @description
                         * See {@link ng.$filterProvider#register $filterProvider.register()}.
                         */
                        filter: invokeLater('$filterProvider', 'register'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#controller
                         * @methodOf angular.Module
                         * @param {string|Object} name Controller name, or an object map of controllers where the
                         *    keys are the names and the values are the constructors.
                         * @param {Function} constructor Controller constructor function.
                         * @description
                         * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
                         */
                        controller: invokeLater('$controllerProvider', 'register'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#directive
                         * @methodOf angular.Module
                         * @param {string|Object} name Directive name, or an object map of directives where the
                         *    keys are the names and the values are the factories.
                         * @param {Function} directiveFactory Factory function for creating new instance of
                         * directives.
                         * @description
                         * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}.
                         */
                        directive: invokeLater('$compileProvider', 'directive'),

                        /**
                         * @ngdoc method
                         * @name angular.Module#config
                         * @methodOf angular.Module
                         * @param {Function} configFn Execute this function on module load. Useful for service
                         *    configuration.
                         * @description
                         * Use this method to register work which needs to be performed on module loading.
                         */
                        config: config,

                        /**
                         * @ngdoc method
                         * @name angular.Module#run
                         * @methodOf angular.Module
                         * @param {Function} initializationFn Execute this function after injector creation.
                         *    Useful for application initialization.
                         * @description
                         * Use this method to register work which should be performed when the injector is done
                         * loading all modules.
                         */
                        run: function (block) {
                            runBlocks.push(block);
                            return this;
                        }
                    };

                    if (configFn) {
                        config(configFn);
                    }

                    return moduleInstance;

                    /**
                     * @param {string} provider
                     * @param {string} method
                     * @param {String=} insertMethod
                     * @returns {angular.Module}
                     */
                    function invokeLater(provider, method, insertMethod) {
                        return function () {
                            invokeQueue[insertMethod || 'push']([provider, method, arguments]);
                            return moduleInstance;
                        };
                    }
                });
            };
        });

    }

    setupModuleLoader(window);
})(window);

/**
 * Closure compiler type information
 *
 * @typedef { {
 *   requires: !Array.<string>,
 *   invokeQueue: !Array.<Array.<*>>,
 *
 *   service: function(string, Function):angular.Module,
 *   factory: function(string, Function):angular.Module,
 *   value: function(string, *):angular.Module,
 *
 *   filter: function(string, Function):angular.Module,
 *
 *   init: function(Function):angular.Module
 * } }
 */
angular.Module;

